package com.castbefore.padgettbusiness.web.client;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.logging.Logger;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.castbefore.padgettbusiness.business.Fields;
import com.castbefore.padgettbusiness.business.PadgettBusinessConstants;
import com.google.appengine.api.datastore.DatastoreFailureException;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

@SuppressWarnings("serial")
public class BusinessClientServlet extends HttpServlet {
	private static final Logger log = Logger
			.getLogger(BusinessClientServlet.class.getName());

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		ArrayList<String> errors = new ArrayList<String>();
		String returnPage = PadgettBusinessConstants.BUSINESS_CLIENT_PAGE;
		/**
		 * Determine whether there is existing client.
		 */
		String clientKey = request.getParameter("ClientKey");
		if (clientKey != null) {
			// Retrieve existing client and display.
			DatastoreService datastore = DatastoreServiceFactory
					.getDatastoreService();
			try {
				Entity client = datastore
						.get(KeyFactory.stringToKey(clientKey));
				request.setAttribute("Client", client);
				request.setAttribute("ClientKey",KeyFactory.keyToString(client.getKey()));
			} catch (EntityNotFoundException e) {
				log.severe(e.getMessage());
			}
		}
		request.setAttribute(PadgettBusinessConstants.ERRORS, errors);
		RequestDispatcher dispatcher = request.getRequestDispatcher(returnPage);
		try {
			dispatcher.forward(request, response);
		} catch (ServletException e) {
			response.sendRedirect(PadgettBusinessConstants.HOME);
		}
	}

	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ArrayList<String> errors = new ArrayList<String>();
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		request.setAttribute("user", user);
		String returnPage = PadgettBusinessConstants.BUSINESS_CLIENT_PAGE;
		//Map<String, String> params = request.getParameterMap();
		Entity client = new Entity("Client", user.getUserId());
		for (String field : Fields.BUSINESS_CLIENTS) {
			String param = null;
			if (request.getParameter(field) != null) {
				try {
					param = (String) (request.getParameter(field));
				} catch (Exception e) {
					e.printStackTrace();
				}
				if (param == null) {
					client.setProperty(field, param);
				} else {
					if (param == "ExpiryDate") {
						try {
							Date expiryDate = PadgettBusinessConstants.padgettDateFormat
									.parse((String) client
											.getProperty("ExpiryDate"));
							client.setProperty("ExpiryDate", expiryDate);
						} catch (ParseException e) {
							log.severe(e.getMessage());
						}
					} else if (param == "EffectiveDate") {
						try {
							Date effectiveDate = PadgettBusinessConstants.padgettDateFormat
									.parse((String) client
											.getProperty("EffectiveDate"));
							client.setProperty("EffectiveDate", effectiveDate);
						} catch (ParseException e) {
							log.severe(e.getMessage());
						}
					} else if (param == "FiscalYearEnd") {
						try {
							Date fiscalYearEnd = PadgettBusinessConstants.padgettDateFormat
									.parse((String) client
											.getProperty("FiscalYearEnd"));
							client.setProperty("FiscalYearEnd", fiscalYearEnd);
						} catch (ParseException e) {
							log.severe(e.getMessage());
						}
					} else {
						client.setProperty(field, param);
					}
				}
			} else {
				client.setProperty(field, request.getParameter(field));
			}
		}
		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();
		Transaction transaction = null;
		if (client.getProperty("ClientKey") == null||((String)(client.getProperty("ClientKey"))).equals("")) {
			client.removeProperty("ClientKey");
			client.setProperty("CreatedDate",new Date(System.currentTimeMillis()));
			client.setProperty("CreatedBy",user);
			client.setProperty("LastModifiedDate",new Date(System.currentTimeMillis()));
			client.setProperty("LastModifiedBy",user);
			try {
				transaction = datastore.beginTransaction();
				datastore.put(client);
				transaction.commit();
				request.setAttribute("Client", client.getProperties());
				request.setAttribute("ClientKey",KeyFactory.keyToString(client.getKey()));
			} catch (IllegalStateException ise) {
				errors.add("Transaction was completed.");
				log.severe(ise.getMessage());
			} catch (DatastoreFailureException dfe) {
				errors.add("Datastore failure.");
				log.severe(dfe.getMessage());
			} catch (ConcurrentModificationException cme) {
				errors.add("Datastore failure.");
				log.severe(cme.getMessage());
			} finally {
				if (transaction.isActive()) {
					transaction.rollback();
					request.removeAttribute("ClientKey");
					request.removeAttribute("Client");
				}
			}
		} else {
			String clientKey = (String) client.getProperty("ClientKey");
			client.removeProperty("ClientKey");
			// Retrieve existing client and overwrite existing
			try {
				Entity existingClient = datastore.get(KeyFactory
						.stringToKey(clientKey));
				existingClient.setPropertiesFrom(client);
				existingClient.setProperty("LastModifiedDate",new Date(System.currentTimeMillis()));
				existingClient.setProperty("LastModifiedBy",user);
				transaction = datastore.beginTransaction();
				datastore.put(existingClient);
				transaction.commit();
				request.setAttribute("Client", existingClient);
				request.setAttribute("ClientKey",KeyFactory.keyToString(existingClient.getKey()));
			} catch (EntityNotFoundException e) {
				errors.add("Client could not be found.");
				log.severe(e.getMessage());
			} finally {
				if (transaction!=null&&transaction.isActive()) {
					transaction.rollback();
				}
			}
		}
		request.setAttribute(PadgettBusinessConstants.ERRORS, errors);
		RequestDispatcher dispatcher = request.getRequestDispatcher(returnPage);
		try {
			dispatcher.forward(request, response);
		} catch (ServletException e) {
			response.sendRedirect(PadgettBusinessConstants.HOME);
		}
	}

}
